﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.LIB;
using YArchitech.Revit;
using HYCodeBase.WinForm;
using YRevitJig;
using HYView;

namespace HYIndicateDimension.BreakLine
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	internal class BreakLineCmd : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			UIApplication application = commandData.Application;
			this.m_uidoc = application.ActiveUIDocument;
			Document document = this.m_uidoc.Document;
			CmdViewType types = (CmdViewType)107;
			if (SwitchView.SetUsableView(types, commandData) != Autodesk.Revit.UI.Result.Succeeded)
			{
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			this.CreateSketchPlan();
			DrawJigCurve drawJigCurve = new DrawJigCurve(this.m_uidoc);
			this.m_uidoc.GetOpenUIViews();
			int left = 0;
			int top = 0;
			if (BreakLineCmd._hWndRevit == null)
			{
				BreakLineCmd._hWndRevit = new WindowHandle(Process.GetCurrentProcess().MainWindowHandle);
			}
			FormSelectDrawType formSelectDrawType = new FormSelectDrawType(BreakLineCmd._hWndRevit, left, top);
			formSelectDrawType.Show(BreakLineCmd._hWndRevit);
			int wMsg = 7;
			BreakLineCmd.SendMessage(BreakLineCmd._hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			for (;;)
			{
				Transaction transaction = new Transaction(document, "Create BreakLine");
				transaction.Start();
				try
				{
					XYZ xyz = null;
					new List<Curve>();
					BreakLineCmd.DirType nSelection = (BreakLineCmd.DirType)formSelectDrawType.m_nSelection;
					Line line = null;
					int lineByJig = this.GetLineByJig(drawJigCurve, nSelection, formSelectDrawType, ref line, ref xyz);
					if (lineByJig == 0)
					{
						transaction.RollBack();
						continue;
					}
					if (lineByJig == 2)
					{
						transaction.RollBack();
						formSelectDrawType.Close();
						this.m_uidoc.RefreshActiveView();
						return Autodesk.Revit.UI.Result.Succeeded;
					}
					if (line.Length < 0.008)
					{
						TaskDialog.Show("提示", "起终点距离太短！");
						transaction.RollBack();
						return Autodesk.Revit.UI.Result.Cancelled;
					}
					XYZ xyz2 = line.Evaluate(0.5, true);
					ElementId id = document.Create.NewModelCurve(line, this.m_uidoc.ActiveView.SketchPlane).Id;
					document.Regenerate();
					XYZ xyz3 = xyz2;
					Line line2 = null;
					Result result = drawJigCurve.DrawJigCurveLine(ref line2, ref xyz3, "", "请选择遮罩方向");
					document.Delete(id);
					if (result == Autodesk.Revit.UI.Result.Cancelled && nSelection != (BreakLineCmd.DirType)formSelectDrawType.m_nSelection)
					{
						transaction.RollBack();
						continue;
					}
					if (result != Result.Succeeded || line == null)
					{
						transaction.RollBack();
						formSelectDrawType.Close();
						return Autodesk.Revit.UI.Result.Cancelled;
					}
					XYZ ptvec = xyz3;
					if (!this.CreateBreakLine(line, ptvec))
					{
						formSelectDrawType.Close();
						transaction.RollBack();
						return Autodesk.Revit.UI.Result.Failed;
					}
					transaction.Commit();
					continue;
				}
				catch (Exception)
				{
					formSelectDrawType.Close();
					transaction.RollBack();
				}
				break;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private int GetLineByJig(DrawJigCurve drawJigCurve, BreakLineCmd.DirType kDirType, FormSelectDrawType form, ref Line line, ref XYZ ptLast)
		{
			string strPromptStart = "请输入起点";
			string strPromptEnd = "请输入终点";
			Result result;
			if (kDirType == BreakLineCmd.DirType.eXDir)
			{
				result = drawJigCurve.DrawJigCurveLineXDirection(ref line, ref ptLast, strPromptStart, strPromptEnd);
			}
			else if (kDirType == BreakLineCmd.DirType.eYDir)
			{
				result = drawJigCurve.DrawJigCurveLineYDirection(ref line, ref ptLast, strPromptStart, strPromptEnd);
			}
			else
			{
				result = drawJigCurve.DrawJigCurveLine(ref line, ref ptLast, strPromptStart, strPromptEnd);
			}
			if (result == Autodesk.Revit.UI.Result.Cancelled && kDirType != (BreakLineCmd.DirType)form.m_nSelection)
			{
				return 0;
			}
			if (result != Result.Succeeded || line == null)
			{
				return 2;
			}
			return 1;
		}

		private bool CreateSketchPlan()
		{
			Autodesk.Revit.DB.View activeView = this.m_uidoc.ActiveView;
			if (activeView.SketchPlane == null)
			{
				Transaction transaction = new Transaction(this.m_uidoc.Document, "创建工作平面");
				try
				{
					transaction.Start();
					Plane plane = RevitVersionFuncs.CreatePlanByOriginAndBasis(activeView.Origin, activeView.RightDirection, activeView.UpDirection);
					SketchPlane sketchPlane = RevitVersionFuncs.NewSketchPlane(this.m_uidoc.Document, plane);
					activeView.SketchPlane = sketchPlane;
					transaction.Commit();
				}
				catch (Exception)
				{
					if (transaction.IsValidObject && transaction.HasStarted())
					{
						transaction.RollBack();
					}
					return false;
				}
				return true;
			}
			return true;
		}

		private bool LoadFamily(Autodesk.Revit.DB.Document doc)
		{
			string text = Product.InstallLocation + "\\FamilyLib\\Family";
			string versionNumber = doc.Application.VersionNumber;
			string text2 = "折断线-有角度";
			text = string.Concat(new string[]
			{
				text,
				"\\",
				versionNumber,
				"\\CuttingLine\\",
				text2,
				".rfa"
			});
			if (!File.Exists(text))
			{
				YJKMessageBox.Show(text + "文件不存在。");
				return false;
			}
			doc.LoadFamily(text);
			return true;
		}

		private FamilyInstance CreateFamilyInstance(XYZ point, Autodesk.Revit.DB.Document doc)
		{
			FamilySymbol familySymbol = null;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).ToElements())
			{
				FamilySymbol familySymbol2 = element as FamilySymbol;
				if (familySymbol2.Family.Name != null && "折断线-有角度" == familySymbol2.Family.Name)
				{
					familySymbol = familySymbol2;
					break;
				}
			}
			if (familySymbol == null)
			{
				return null;
			}
			RevitVersionFuncs.FamilySymbolActivate(familySymbol);
			return doc.Create.NewFamilyInstance(point, familySymbol, doc.ActiveView);
		}

		private bool CreateBreakLine(Line line, XYZ ptvec)
		{
			Document document = this.m_uidoc.Document;
			XYZ xyz = line.GetEndPoint(0);
			XYZ xyz2 = line.GetEndPoint(1);
			XYZ point = (xyz + xyz2) / 2.0;
			double num = xyz.DistanceTo(xyz2);
			double num2 = num / 2.0;
			double num3 = num / 2.0;
			double num4 = (double)document.ActiveView.Scale / 100.0;
			double num5 = 0.73818897637795278 * num4;
			double num6 = 1.3779527559055118 * num4;
			if (!this.LoadFamily(document))
			{
				return false;
			}
			XYZ xyz3 = (xyz2 - xyz).Normalize();
			XYZ xyz4 = (ptvec - xyz).Normalize();
			XYZ viewDirection = this.m_uidoc.ActiveView.ViewDirection;
			if (xyz3.AngleOnPlaneTo(xyz4, viewDirection) > Math.PI*.5)
			{
				XYZ xyz5 = xyz2;
				xyz2 = xyz;
				xyz = xyz5;
			}
			XYZ xyz6 = xyz2 - xyz;
			double num7 = this.m_uidoc.ActiveView.RightDirection.AngleOnPlaneTo(xyz6.Normalize(), viewDirection);
			FamilyInstance familyInstance = this.CreateFamilyInstance(point, document);
			if (familyInstance == null)
			{
				TaskDialog.Show("提示", "创建折断线失败！");
				return false;
			}
			familyInstance.GetParameter("角度").Set(num7);
			familyInstance.GetParameter("右").Set(num3);
			familyInstance.GetParameter("左").Set(num2);
			familyInstance.GetParameter("遮罩区域长度").Set(num);
			familyInstance.GetParameter("锯齿宽度").Set(num5);
			familyInstance.GetParameter("锯齿深度").Set(num6);
			document.Regenerate();
			XYZ facingOrientation = familyInstance.FacingOrientation;
			if (facingOrientation.X < 0.0 || facingOrientation.Y < 0.0 || facingOrientation.Z < 0.0)
			{
				familyInstance.GetParameter("角度").Set(num7 - Math.PI);
			}
			return true;
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public static WindowHandle _hWndRevit;

		public UIDocument m_uidoc;

		private enum DirType
		{
			eYDir,
			eXDir,
			eFreeDir
		}
	}
}
